<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>

    <!-- 对象是__proto__    就是寻找对象Prototype上的属性和方法--   Prototype    -->
    <!-- 函数也是对象             -->
    <!-- Object  Array    都是一个函数   通过构造函数实例化把一些方法放在了构造原型上 -->
    <script>
        //   console.log(window);
        // console.log(Array,'ma');
        // 对象的隐式原型的值等于对应构造函数的显式原型的值
        // obj 实例对象的  隐式原型__proto__  ==  Person构造函数的  显示原型 prototype
        // 在Javascript 语言中，constructor 属性是专门为 function 而设计的，它存在于每一个function 的prototype 属性中。这个constructor 保存了指向 function 的一个引用。 
        function Person(obj) {
            this.name = obj.name
        }
        Person.prototype.Getname = function () {
            console.log(this.name);
        }
        // console.log(Person.prototype, 'llllllllllll');
        let obj = new Person({ name: '马英鹏' })
        //    console.log(Person.prototype.Getname,'????');
        //    console.log(obj,'/aaaaaaaa');
        //    console.log(Person,'????11111111111111111222222222222222');
        //    console.log(obj.__proto__.__proto__.__proto__ ,'__proto__');
        console.log(Person.prototype.__proto__, obj.__proto__, '函数的原型和构造函数的__proto__');
        console.log(Object.prototype, Person.prototype.__proto__, 'Object的原型');
        //    console.log(Person.prototype ,'prototype');
        // console.log(obj, '实例化对象');
        // console.log( Object.toString.call(),'????111111111');
        // console.log( Object.prototype,'????22222222');
        //    obj.Getname()
        //    console.log(Object.prototype.toString.call(''));

        // 我们创建一个函数A(就是声明一个函数), 那么浏览器就会在内存中创建一个对象B，而且每个函数都默认会有一个属性 prototype
        // 指向了这个对象( 即：prototype的属性的值是这个对象 )。这个对象B就是函数A的原型对象，简称函数的原型。这个原型对象B 默认会有一个属性 constructor
        // 指向了这个函数A ( 意思就是说：constructor属性的值是函数A )。
        // function fn() {
        //     console.log('fn函数');
        // }
        // console.log(fn.prototype.constructor, '/?');
        //------------------------------------------------------------------

        //     当你在定义一个函数（代码如下所示）时，

        // function Fn() 

        // {

        // // some code

        // }

        //  JavaScript 内部会执行如下几个动作：1

        // 1. 第一步为该函数添加一个原形（即 prototype）属性 （这是一个对象）
        // 2. 第二步为 prototype 对象额外添加一个 constructor 属性，并且该属性保存指向函数F 的一个引用（constructor 属性指向定义的函数Fn）


        function ma() {

        }

        var aa = new ma()
        console.log(aa, 'aa');
        console.log(aa.__proto__, '实例的__proto__');
        console.log(Object, 'object'); //  ƒ Object() { [native code] } 'object'
        console.log(Array, 'object'); // ƒ Array() { [native code] } 'object'
        console.log(String); // ƒ String() { [native code] }
        console.log(Boolean); // ƒ Boolean() { [native code] }
        console.log(undefined);
        console.log(null);
        console.log(Date);
        console.log(RegExp);

        // console.log([1,2]);
        // console.log(ma.__proto__, '函数__proto__');
        // console.log(ma.prototype, '函数的prototype');
        // console.log(aa.prototype, '函数的prototype');  //undefined
        // console.log(ma.prototype===aa.__proto__, '函数的原型对象和实例的原型对象');
        // console.log(Object.__proto__.constructor, 'Object.__proto__.constructor');
        // console.log(Object.__proto__, 'Object.__proto__');
        //    console.log(ma.__proto__.constructor,'自己定义的函数');
        //    console.log(ma.__proto__.constructor===Object.__proto__.constructor,'rrrrrrrr');
    //  console.log(ma.prototype,'llllllaaaaaaaaaaaa');
    //  console.log(ma.__proto__,'llllllaaaaaaaaaaaa');
    //  console.log(ma.prototype===aa.__proto__,'llllllaaaaaaaaaaaa');
    //  console.log(Object.__proto__ , Function.prototype);



    </script>
</body>

</html>